package org.hepeng.commons.spring.web;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.web.PortResolver;
import org.springframework.security.web.PortResolverImpl;
import org.springframework.security.web.savedrequest.HttpSessionRequestCache;
import org.springframework.security.web.util.matcher.AnyRequestMatcher;
import org.springframework.security.web.util.matcher.RequestMatcher;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @author he peng
 */
public class OriginalRequestUrlHttpSessionRequestCache extends HttpSessionRequestCache {

    private static final Logger LOG = LoggerFactory.getLogger(OriginalRequestUrlHttpSessionRequestCache.class);

    private static final PortResolver DEFAULT_PORT_RESOLVER = new PortResolverImpl();
    private RequestMatcher requestMatcher = AnyRequestMatcher.INSTANCE;
    private boolean createSessionAllowed = true;
    private String sessionKeyName = "ORIGINAL_REQUEST_URL_SAVED_REQUEST";
    private static final String ORIGINAL_REQUEST_URL_KEY = "originalRequestUrl";
    private String originalRequestUrlVarName = ORIGINAL_REQUEST_URL_KEY;

    public OriginalRequestUrlHttpSessionRequestCache() {
        super.setSessionAttrName(this.sessionKeyName);
        super.setCreateSessionAllowed(this.createSessionAllowed);
        super.setRequestMatcher(requestMatcher);
        super.setPortResolver(DEFAULT_PORT_RESOLVER);

        if (StringUtils.isBlank(this.originalRequestUrlVarName)) {
            this.originalRequestUrlVarName = System.getProperty("original.request.url.var.name");
        }
    }

    public OriginalRequestUrlHttpSessionRequestCache(String originalRequestUrlVarName) {
        this.originalRequestUrlVarName = originalRequestUrlVarName;
    }

    @Override
    public void saveRequest(HttpServletRequest request, HttpServletResponse response) {
        if (requestMatcher.matches(request)) {
            OriginalRequestUrlSavedRequest savedRequest = new OriginalRequestUrlSavedRequest(request);
            String originalRequestUrl = request.getHeader(this.originalRequestUrlVarName);
            if (StringUtils.isBlank(originalRequestUrl)) {
                originalRequestUrl = request.getParameter(this.originalRequestUrlVarName);
            } else {
                originalRequestUrl = request.getRequestURL().toString();
            }

            savedRequest.setOriginalRequestUrl(originalRequestUrl);
            if (createSessionAllowed || request.getSession(false) != null) {
                // Store the HTTP request itself. Used by
                // AbstractAuthenticationProcessingFilter
                // for redirection after successful authentication (SEC-29)
                request.getSession().setAttribute(this.sessionKeyName, savedRequest);
                LOG.debug("OriginalRequestUrlSavedRequest added to Session: " + savedRequest);
            }
        }
        else {
            LOG.debug("Request not saved as configured RequestMatcher did not match");
        }
    }

}
